package com.goal98.team.controllers

import org.springframework.security.providers.UsernamePasswordAuthenticationToken as AuthToken
import org.springframework.security.context.SecurityContextHolder as SCH
import javax.servlet.http.HttpServletRequest
import com.goal98.team.domain.Person
import com.goal98.team.domain.Position
import com.goal98.team.domain.Authority
import org.springframework.security.context.SecurityContextHolder
import com.goal98.team.Constants.Events

/**
 * Registration controller.
 */
class RegisterController {

    def authenticateService
    def daoAuthenticationProvider
    def emailerService

    static Map allowedMethods = [save: 'POST', update: 'POST']

    /**
     * User Registration Top page.
     */
    def index = {

        // skip if already logged in
        if (authenticateService.isLoggedIn()) {
            redirect action: show
            return
        }

        if (session.id) {
            def person = new Person()
            person.properties = params
            return [person: person]
        }

        redirect uri: '/'
    }

    def activate = {

        // skip if already logged in
        if (authenticateService.isLoggedIn()) {
            redirect action: show
            return
        }

        if (session.id) {
            def userName = params.userName
            def person = Person.findByUsername(userName)
            if (!person || person.enabled) {
                redirect uri: '/'
                return
            } else {
                person.properties = params
                return [person: person]
            }
        }

        redirect uri: '/'
    }

    def activateUpdate = {
        // skip if already logged in
        if (authenticateService.isLoggedIn()) {
            redirect action: show
            return
        }

        def person = Person.findByUsername(params.username)
        person = Person.get(person.id)
        person.properties = params



        if (params.captcha.toUpperCase() != session.captcha) {
            person.passwd = ''
            flash.message = message(code: 'register.captcha.notmatch.message', 'default': 'Access code did not match.')
            render view: 'index', model: [person: person]
            return
        }

        if (!params.passwd || !params.repasswd) {
            person.passwd = ''
            flash.message = message(code: 'register.password.empty.message', 'default': 'The passwords you entered must not be empty.')
            render view: 'index', model: [person: person]
            return
        }

        if (params.passwd != params.repasswd) {
            person.passwd = ''
            flash.message = message(code: 'register.password.notmatch.message', 'default': 'The passwords you entered do not match.')
            render view: 'index', model: [person: person]
            return
        }

        def pass = authenticateService.encodePassword(params.passwd)
        person.passwd = pass
        person.enabled = true
        person.emailShow = true
        person.description = ''
        if (person.save()) {
//            role.addToPeople(person)
            sendRegMail(person, request, params)

            person.save(flush: true)

            def auth = new AuthToken(person.username, params.passwd)
            def authtoken = daoAuthenticationProvider.authenticate(auth)
            SecurityContextHolder.context.authentication = authtoken
            redirect uri: '/'
        }
        else {
            person.passwd = ''
            render view: 'activate', model: [person: person]
        }

    }

    private def sendRegMail(person, HttpServletRequest request, Map params) {
        def config = authenticateService.securityConfig
        publishEvent(Constants.Events.USER_ACTIVATED.toString(),
                [to:person.username,
                subject:message(code: 'register.email.subject', 'default': '{0} Account Signed Up', args: [request.serverName]),
                        emailContent:g.render(template: '/email/registrationInfo', model: [request: request, person: person, params: params])
                ])
        if (config.security.useMail) {
            flash.message = "${message(code: 'register.success.message', 'default': 'A email has been sent to {0}', args: [person.username])}"
        }


    }

    /**
     * User Information page for current user.
     */
    def show = {

        // get user id from session's domain class.
        def user = authenticateService.userDomain()
        if (user) {
            render view: 'show', model: [person: Person.get(user.id)]
        }
        else {
            redirect action: index
        }
    }

    /**
     * Edit page for current user.
     */
    def edit = {

        def person
        def user = authenticateService.userDomain()
        if (user) {
            person = Person.get(user.id)
        }

        if (!person) {
            flash.message = "[Illegal Access] User not found with id ${params.id}"
            redirect action: index
            return
        }

        [person: person]
    }

    /**
     * update action for current user's edit page
     */
    def update = {

        def person
        def user = authenticateService.userDomain()
        if (user) {
            person = Person.get(user.id)
        }
        else {
            redirect action: index
            return
        }

        if (!person) {
            flash.message = "[Illegal Access] User not found with id ${params.id}"
            redirect action: index, id: params.id
            return
        }

        // if user want to change password. leave passwd field blank, passwd will not change.
        if (params.passwd && params.passwd.length() > 0
                && params.repasswd && params.repasswd.length() > 0) {
            if (params.passwd == params.repasswd) {
                person.passwd = authenticateService.encodePassword(params.passwd)
            }
            else {
                person.passwd = ''
                flash.message = 'The passwords you entered do not match.'
                render view: 'edit', model: [person: person]
                return
            }
        }

        person.position = Position.get(params.'position.id')

        person.userRealName = params.userRealName
		person.receiveEmail = params.receiveEmail?true:false
        if (params.emailShow) {
            person.emailShow = true
        }
        else {
            person.emailShow = false
        }

        if (person.save()) {
            redirect action: show, id: person.id
        }
        else {
            render view: 'edit', model: [person: person]
        }
    }

    /**
     * Person save action.
     */
    def save = {

        // skip if already logged in
        if (authenticateService.isLoggedIn()) {
            redirect action: show
            return
        }

        def person = new Person()
        person.properties = params

        def config = authenticateService.securityConfig
        def defaultRole = config.security.defaultRole

        def role = Authority.findByAuthority(defaultRole)
        if (!role) {
            person.passwd = ''
            flash.message = 'Default Role not found.'
            render view: 'index', model: [person: person]
            return
        }

        if (params.captcha.toUpperCase() != session.captcha) {
            person.passwd = ''
            flash.message = message(code: 'register.captcha.notmatch.message', 'default': 'Access code did not match.')
            render view: 'index', model: [person: person]
            return
        }

        if (!params.passwd || !params.repasswd) {
            person.passwd = ''
            flash.message = message(code: 'register.password.empty.message', 'default': 'The passwords you entered must not be empty.')
            render view: 'index', model: [person: person]
            return
        }

        if (params.passwd != params.repasswd) {
            person.passwd = ''
            flash.message = message(code: 'register.password.notmatch.message', 'default': 'The passwords you entered do not match.')
            render view: 'index', model: [person: person]
            return
        }

        def pass = authenticateService.encodePassword(params.passwd)
        person.passwd = pass
        person.enabled = true
        person.emailShow = true
        person.description = ''
        if (person.save()) {
            role.addToPeople(person)
            sendRegMail(person, request, params)

            person.save(flush: true)

            def auth = new AuthToken(person.username, params.passwd)
            def authtoken = daoAuthenticationProvider.authenticate(auth)
            SecurityContextHolder.context.authentication = authtoken
            redirect uri: '/'
        }
        else {
            person.passwd = ''
            render view: 'index', model: [person: person]
        }
    }
}
